home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Mark Pilgrim / Jotto ][ 1.2 / source / Wipes ƒ / Hilbert wipe.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-30  |  3.0 KB  |  115 lines  |  [TEXT/MMCC]

  1. #include "timing.h"
  2.  
  3. /* This fills the screen by a Hilbert space-filling curve, which is defined by
  4.    two mutually recursive drawing functions:
  5.    
  6.    X = left, Y, draw, right, X, draw, X, right, draw, Y, left
  7.    Y = right, X, draw, left, Y, draw, Y, left, draw, X, right
  8.    
  9.    Start by drawing X at the highest recursion level from the bottomleft of the
  10.    screen. (At recursion level 1, X and Y are null functions.)
  11. */
  12.  
  13. #define    RecursionLevel    4
  14. #define CorrectTime 1
  15. #define theWindowHeight (boundsRect.bottom-boundsRect.top)
  16. #define theWindowWidth (boundsRect.right-boundsRect.left)
  17.  
  18. pascal void HilbertRecurse(GrafPtr sourceGrafPtr, GrafPtr destGrafPtr, Rect boundsRect,
  19.     short level, short whichpattern, short* x, short* y);
  20. pascal short HilbertWipe(GrafPtr sourceGrafPtr, GrafPtr destGrafPtr, Rect boundsRect);
  21.  
  22. typedef char    Hilby[11];
  23.  
  24. static Hilby    HilbertPattern[]=
  25. {
  26.     {
  27.         0x02,0x69,0x00,0x01,0x42,0x00,0x42,0x01,0x00,0x69,0x02
  28.     },
  29.     {
  30.         0x01,0x42,0x00,0x02,0x69,0x00,0x69,0x02,0x00,0x42,0x01
  31.     }
  32. };
  33.  
  34. static short            HilbertDirection;
  35. static short            vBlockSize;
  36. static short            hBlockSize;
  37. static RgnHandle    boundsRgn;
  38.  
  39. pascal void HilbertRecurse(GrafPtr sourceGrafPtr, GrafPtr destGrafPtr, Rect boundsRect,
  40.     short level, short whichpattern, short* x, short* y)
  41. {
  42.     short            i;
  43.     Rect            source;
  44.     
  45.     for (i=0; i<11; i++)
  46.     {
  47.         switch (HilbertPattern[whichpattern][i])
  48.         {
  49.             case 0x01:     /* turn left */
  50.                 HilbertDirection--;
  51.                 if (HilbertDirection<0) HilbertDirection=3;
  52.                 break;
  53.             case 0x02:     /* turn right */
  54.                 HilbertDirection++;
  55.                 if (HilbertDirection==4) HilbertDirection=0;
  56.                 break;
  57.             case 0x00:    /* draw */
  58.                 StartTiming();
  59.                 SetRect(&source, *x, *y-vBlockSize, *x+hBlockSize, *y);
  60.                 OffsetRect(&source, boundsRect.left, boundsRect.top);
  61.                 CopyBits(&(sourceGrafPtr->portBits), &(destGrafPtr->portBits),
  62.                                 &source, &source, 0, boundsRgn);
  63.                 switch (HilbertDirection)
  64.                 {
  65.                     case 0:
  66.                         *x+=hBlockSize;
  67.                         break;
  68.                     case 1:
  69.                         *y-=vBlockSize;
  70.                         break;
  71.                     case 2:
  72.                         *x-=hBlockSize;
  73.                         break;
  74.                     case 3:
  75.                         *y+=vBlockSize;
  76.                         break;
  77.                 }
  78.                 TimeCorrection(CorrectTime);
  79.                 break;
  80.             case 0x42:    /* call X */
  81.                 if (level>1)
  82.                     HilbertRecurse(sourceGrafPtr,destGrafPtr,boundsRect,level-1,0,x,y);
  83.                 break;
  84.             case 0x69:    /* call Y */
  85.                 if (level>1)
  86.                     HilbertRecurse(sourceGrafPtr,destGrafPtr,boundsRect,level-1,1,x,y);
  87.                 break;
  88.         }
  89.     }
  90. }
  91.  
  92. pascal short HilbertWipe(GrafPtr sourceGrafPtr, GrafPtr destGrafPtr, Rect boundsRect)
  93. {
  94.     short            curx, cury;
  95.     short            answer, i;
  96.     
  97.     answer=1;
  98.     for (i=0; i<RecursionLevel; i++)
  99.         answer*=2;
  100.     vBlockSize=1+theWindowHeight/answer;    /* used to be 20 */
  101.     hBlockSize=1+theWindowWidth/answer;        /* used to be 32 */
  102.     HilbertDirection=0;
  103.     boundsRgn=NewRgn();
  104.     RectRgn(boundsRgn, &boundsRect);
  105.     cury=theWindowHeight;
  106.     curx=0;
  107.     HilbertRecurse(sourceGrafPtr,destGrafPtr,boundsRect,RecursionLevel,0,&curx,&cury);
  108.     CopyBits(&(sourceGrafPtr->portBits), &(destGrafPtr->portBits),
  109.                 &boundsRect, &boundsRect, 0, 0L);  /* in case we missed any bits */
  110.     
  111.     DisposeRgn(boundsRgn);
  112.     
  113.     return 0;
  114. }
  115.